package com.own.dondeestoy;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;

import com.google.android.gms.maps.model.LatLng;
import com.own.dondeestoy.core.Card;
import com.own.dondeestoy.core.Parameter;
import com.own.dondeestoy.logic.LayerLogic;

public class CheckLocationService extends Service implements LocationListener {
	// Privadas

	private String provider;
	private String latituteField;
	private String longitudeField;
	private LayerLogic _logic;
	private static int distance = 1000;
	private static int milliseconds = 300000;
	private static int millisecondsToSleep = 60 * 60 * 100;

	// Publicas
	public static List<Integer> nearLocations;
	public static LocationManager locationManager;
	public static NotificationManager notificationManager;
	public static Timer timer = new Timer();

	public CheckLocationService() {
		// TODO Auto-generated constructor stub
		_logic = new LayerLogic(MainActivity.context);
	}

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@SuppressLint("NewApi")
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// Let it continue running until it is stopped.
		// prepare intent which is triggered if the
		// notification is selected

		timer.scheduleAtFixedRate(new TimerTask() {
			public void run() {
				// the following code should be what is done repeatedly
				// Log.d("MessageService", String.valueOf(++counter));

				getMyLocation();
			}
		}, 0, milliseconds);

		try {

			CheckLocationService.locationManager.requestLocationUpdates(
					LocationManager.NETWORK_PROVIDER, milliseconds, distance,
					this);
		} catch (Exception e) {
			System.err.println(e.getCause());
		}

		try {

			CheckLocationService.locationManager.requestLocationUpdates(
					LocationManager.GPS_PROVIDER, milliseconds, distance, this);

		} catch (Exception e) {
			System.err.println(e.getCause());
		}

		// Este Servicio lo tenemos que usar cuando haya revisado y encontrado
		// algo cerca

		// Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();

		MainActivity.isServiceStarted = true;
		return START_STICKY;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		MainActivity.isServiceStarted = false;
		// Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
	}

	@Override
	public void onLocationChanged(Location location) {

		int lat = (int) (location.getLatitude());
		int lng = (int) (location.getLongitude());
		latituteField = String.valueOf(lat);
		longitudeField = String.valueOf(lng);
		MainActivity.myPosition = new LatLng(location.getLatitude(),
				location.getLongitude());

		isNearToLocation(location);

	}

	@Override
	public void onProviderDisabled(String arg0) {
		// Toast.makeText(this, "Disabled provider " + provider,
		// Toast.LENGTH_SHORT).show();

	}

	@Override
	public void onProviderEnabled(String arg0) {
		// Toast.makeText(this, "Enabled new provider " + provider,
		// Toast.LENGTH_SHORT).show();

	}

	@Override
	public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
		// TODO Auto-generated method stub

	}

	private void isNearToLocation(Location location) {

		// Location locationX = new Location("point A");
		// locationX.setLatitude(location.getLatitude());
		// locationX.setLongitude(location.getLongitude());
		//
		// Location locationY = new Location("point B");
		// locationY.setLatitude(MainActivity.myPosition.latitude);
		// locationY.setLongitude(MainActivity.myPosition.longitude);

		// if (locationX.distanceTo(locationY) <= 10 && MainActivity.cards!=
		// null) {
		// if (MainActivity.cards!=null){
		// showNotifications();
		// }
		// return;
		// }

		// Acá la lógica para buscar y comparar

		List<Card> cards = new ArrayList<Card>();
		nearLocations = new ArrayList<Integer>();
		String typeValues = "1";
		List<Integer> types = new ArrayList<Integer>();
		try {
			typeValues = _logic.getParameterById(3).getValue().replace(".", "");
			for (int i = 0; i <= typeValues.length() - 1; i++) {
				types.add(Integer.valueOf(typeValues.substring(i, i + 1)));
			}
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			types.add(1);
			e1.printStackTrace();
		}
		// llenar la lista de locs con los datos de la tabla - Matata

		try {
			// cards = _logic.getAll();
			cards = _logic.getCardByCardTypes(types);
			// int progress =0;
			// MainActivity.mProgress.setVisibility(View.VISIBLE);
			List<Address> address;
			Geocoder coder = new Geocoder(this);

			for (Card card : cards) {
				// progress = progress + 1;
				// MainActivity.mProgress.setProgress(progress);
				// float[] results = new float[1];
				// Location.distanceBetween(location.getLatitude() / 1e6,
				// location.getLongitude() / 1e6,
				// Double.valueOf(card.getLat()) / 1e6,
				// Double.valueOf(card.getLng()) / 1e6, results);

				if (!card.getLat().equals("")) {

					// address = coder.getFromLocation(
					// Double.valueOf(card.getLat()),
					// Double.valueOf(card.getLng()), 1);
					// if (address == null || address.size() == 0) {
					// Address addressLocation = address.get(0);
					//
					// card.setAddress(addressLocation
					// .getMaxAddressLineIndex() > 0 ? addressLocation
					// .getAddressLine(0) : "" + " "
					// + addressLocation.getLocality());
					//
					// _logic.update(card);
					// }

					double distance;
					Location locationA = new Location("point A");
					locationA.setLatitude(location.getLatitude());
					locationA.setLongitude(location.getLongitude());

					Location locationB = new Location("point B");
					locationB.setLatitude(Double.valueOf(card.getLat()));
					locationB.setLongitude(Double.valueOf(card.getLng()));
					distance = locationA.distanceTo(locationB);

					if (distance <= this.distance) {
						nearLocations.add(card.getId());
					}

				} else {
					// Geocoder coder = new Geocoder(this);
					// List<Address> address;

					try {
						address = coder.getFromLocationName(card.getAddress(),
								5);
						if (address == null || address.size() == 0) {

						} else {
							Address addressLocation = address.get(0);

							card.setLat(String.valueOf(addressLocation
									.getLatitude()));
							card.setLng(String.valueOf(addressLocation
									.getLongitude()));

							_logic.update(card);

							double distance;
							Location locationA = new Location("point A");
							locationA.setLatitude(location.getLatitude());
							locationA.setLongitude(location.getLongitude());

							Location locationB = new Location("point B");
							locationB.setLatitude(Double
									.valueOf(addressLocation.getLatitude()));
							locationB.setLongitude(Double
									.valueOf(addressLocation.getLongitude()));
							distance = locationA.distanceTo(locationB);

							if (distance <= this.distance) {
								nearLocations.add(card.getId());
							}
						}
					} finally {

					}
				}

			}

			if (nearLocations.size() > 0) {
				showNotifications();
			}

			_logic = new LayerLogic(MainActivity.context);
			MainActivity.cards = new ArrayList<Card>();
			try {
				MainActivity.cards = _logic
						.getByIds(CheckLocationService.nearLocations);
				// MainActivity.mProgress.setVisibility(View.INVISIBLE);

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// notifico al UI que hay nuevas cards
		Intent intent = new Intent();
		intent.setAction("com.own.dondeestoy.isneartolocation");
		sendBroadcast(intent); // finally broadcast

	}

	private void getMyLocation() {
		// Actualizo parámetros en la aplicación
		List<Parameter> params = new ArrayList<Parameter>();
		try {
			params = _logic.getAllParameter();
			milliseconds = Integer.valueOf(params.get(0).getValue()) * 60 * 100;
			distance = Integer.valueOf(params.get(1).getValue());
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		// Get the location manager
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		// Define the criteria how to select the locatioin provider -> use
		// default
		Criteria criteria = new Criteria();

		provider = locationManager.getBestProvider(criteria, false);
		Location location = locationManager.getLastKnownLocation(provider);

		// Initialize the location fields
		if (location != null) {
			System.out.println("Provider " + provider + " has been selected.");
			onLocationChanged(location);
			// isNearToLocation(location);
		} else {
			location = locationManager
					.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
			if (location != null) {
				onLocationChanged(location);
				// isNearToLocation(location);
			} else {
				latituteField = ("Location not available");
				longitudeField = ("Location not available");
				try {
					locationManager.requestLocationUpdates(
							LocationManager.NETWORK_PROVIDER, milliseconds,
							distance, this);

				} catch (Exception e) {
					System.err.println(e.getCause());
				}

			}
		}
	}

	@SuppressLint("NewApi")
	private void showNotifications() {

		if (MainActivity.showNotifications) {

			Intent intentNotification = new Intent(this, MainActivity.class);
			PendingIntent pIntent = PendingIntent.getActivity(this, 0,
					intentNotification, 0);

			// build notification
			// the addAction re-use the same intent to keep the example short
			Notification n = new Notification.Builder(this)
					.setContentTitle("Lugares cercanos")
					.setContentText("No te los pierdas!")
					.setSmallIcon(R.drawable.dondeestoynotif01)
					.setContentIntent(pIntent)
					.setAutoCancel(true)
//					.setSound(
//							RingtoneManager
//									.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
					.addAction(0, "Ir a detalle", pIntent).build();

			notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);


			notificationManager.notify(0, n);
			
			MainActivity.showNotifications = false;
		}
		// Api 11
		// Notification noti = new Notification.Builder(this)
		// .setContentTitle("New mail from ")
		// .setContentText("")
		// .setSmallIcon(R.drawable.cupcake01)
		// .setLargeIcon(R.drawable.cupcake01)
		// .build();
	}

}
